#ifndef CONSTRUITCLASSE_H
#define CONSTRUITCLASSE_H

#include "BaseUI.h"
#include <map>

//#include "ADD.h"
#include "CompetenceClasse.h"
#include "EnsembleCompetencesClasse.h"

class QVBoxLayout;
class QGroupBox;
class QPushButton;
class QLCDNumber;
class QButtonGroup;
class QSpinBox;
class QComboBox;

class Key;

class Classe;

/**
 * Classe permettant de déterminer les restrictions et compétences de
 * classe, ainsi que le nombre de XP de départ.
 *
 * On récupère l'ensemble des compétences et restrictions existantes,
 * ainsi que les éventuels ensembles de compétences. Ces dernier
 * peuvent être gratuits (et obligatoires) pour les Spécialistes par
 * exemples, ou alors payants (et optionels comme un "racourci"),
 * comme pour les Druides, Clercs.
 *
 * @todo Dans le cas d'ensembles optionels, il faut également prévoir
 * un mécanisme de remise à zéro rapide (càd un ensemble "vide").
 *
 * @author Johan "Solo" Luisier
 */
class ConstruitClasse : public BaseUI
{
  Q_OBJECT
 public:
  ConstruitClasse( Classe* classe, const std::string& race,
		   const std::vector< unsigned > & valTraits, const int& pp,
		   QWidget* parent = 0 );
  ~ConstruitClasse();
  StatusCode classeChoisie();
  static void setLevel( const DebugLevelType& level, const unsigned& );
 protected:
  QGroupBox
    *boite,    /**< Groupe "physique" des compétences */
    *boiteRes, /**< Groupe "physique" des restrictions */
    *boiteEns, /**< Groupe "physique" des ensembles de compétences */
    *boiteXp;  /**< Groupe "physique" qui permet d'entrer le nombre de
		  XP */
  /**
   * Groupe "logique" de tous les boutons existants (autant les
   * restrictions que les compétences).
   */
  QButtonGroup *groupe;
  /**
   * Liste des ensembles de compétences existants.
   */
  QComboBox *listeEns;
  /**
   * Affichage du nombre de PP restants.
   */
  QLCDNumber *nbrPP;
  /**
   * Outil de sélection du nombre de point d'expérience de la
   * Classe. Sert à créer un PJ ayant déjà de l'expérience.
   */
  QSpinBox *nbrXP;
  int PP, /**< Nombre de PP que l'on peut dépenser lors de la
	     création */
    derniereComp; /**< Numéro du dernier bouton correspondant à une
		     compétence */
  unsigned int
    nbrComp,    /**< Nombre de compétences */
    nbrRes,     /**< Nombre de restrictions */
    nbrEns,     /**< Nombre d'ensembles de compétences */
    nbrCompEns; /**< Nombre maximal de compétences dans un ensemble */
  std::vector<CompetenceClasse>
    Competences,  /**< Contient toutes les compétences disponibles */
    Restrictions; /**< Contient toutes les restrictions disponibles */
  /**
   * Contient les noms des éventuels ensembles de compétences, avec
   * leur coût.
   */
  std::vector< EnsembleCompetencesClasse > Ensembles;
 private:
  void preparerAffichage();
  void analyseListe();
  void ajouterCompetence(const int& comp);
  void ajouterRestriction(const int& res);
  void choixEnsemble(const int& ens);
  void prepareEnsCompetences();
  std::vector< unsigned > ValeursTraits;
  /**
   * Pointeur sur la classe qui est construite à partir de la fenêtre,
   */
  Classe *mClasse;
  std::vector<bool>
    aCompRes,     /**< Contient \e true si la compétence / restriction
		     est séléctionnée */
    etatsTriples; /**< Contient \e true si la compétence est
		     représentée par un boutons trinaire */
  /**
   * Table de correspondance entre le numéro du bouton (et son état)
   * et le numéro de la compétence (ou restriction).
   */
  std::map<Key, unsigned int> mapEtatsTriples;
  /**
   * Sert à savoir si on peut annuler le choix d'un ensemble, càd
   * choisir un ensemble "vide".
   */
  bool annuleEnsemble;
  /**
   * Nom de la Race du futur PJ, sert lors du contrôle des prérequis.
   */
  std::string mRace;
  /**
   * Niveau de sortie relatif au traitement de la liste de
   * compétences.
   */
  static DebugLevelType gestionListe;
  /**
   * Permet de mapper une compétence à tiroir avec l'ensemble des
   * compétences sélectionnées.
   */
  std::map< unsigned int, std::vector< unsigned int > > mapTiroirs;
  private slots:
  void fermer();
  void ajouter(const int& bouton);
  void miseAJour();
};

#endif // CONSTRUITCLASSE_H
